/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package demoproxy;

import java.io.IOException;
import java.io.*;
import java.net.*;
/**
 *
 * @author nhok_bi
 */
public class Demoproxy {

    /**
     * @param args the command line arguments
     */
   public static void main(String[] args) throws IOException {
    try {
      String host = "your Proxy Server";
      int remoteport = 100;
      int localport = 111;
      // in ra dong tin nhan 
      System.out.println("Starting proxy for " + host + ":" + remoteport
          + " on port " + localport);
      // bat dau chay sever
      runServer(host, remoteport, localport); // 
    } catch (Exception e) {
      System.err.println(e);
    }
  }

  /**
   * runs a single-threaded proxy server on
   * the specified local port. It never returns.
   */
  public static void runServer(String host, int remoteport, int localport)
      throws IOException {
      //tạo ra socket lắng nghe kết nối
    ServerSocket ss = new ServerSocket(localport);

    final byte[] request = new byte[1024];
    byte[] reply = new byte[4096];

    while (true) {
      Socket client = null, server = null;
      try {
        //chờ kết nối đến port
        client = ss.accept();

        final InputStream streamFromClient = client.getInputStream();
        final OutputStream streamToClient = client.getOutputStream();

        // tạo kết nối đến server
        //nếu kết nối server lỗi thì gửi lỗi về cho client, ngắt kết nối, và chờ kết nối lại
        try {
          server = new Socket(host, remoteport);
        } catch (IOException e) {
          PrintWriter out = new PrintWriter(streamToClient);
          out.print("Proxy server cannot connect to " + host + ":"
              + remoteport + ":\n" + e + "\n");
          out.flush();
          client.close();
          continue;
        }

        final InputStream streamFromServer = server.getInputStream();
        final OutputStream streamToServer = server.getOutputStream();
        //chưa hiểu cái thread làm j lắm
        // a thread to read the client's requests and pass them
        // to the server. A separate thread for asynchronous.
        Thread t = new Thread() {
          public void run() {
            int bytesRead;
            try {
              while ((bytesRead = streamFromClient.read(request)) != -1) {
                streamToServer.write(request, 0, bytesRead);
                streamToServer.flush();
              }
            } catch (IOException e) {
            }

            // the client closed the connection to us, so close our
            // connection to the server.
            try {
              streamToServer.close();
            } catch (IOException e) {
            }
          }
        };

        // Start the client-to-server request thread running
        t.start();

        // Read the server's responses
        // and pass them back to the client.
        int bytesRead;
        try {
          while ((bytesRead = streamFromServer.read(reply)) != -1) {
            streamToClient.write(reply, 0, bytesRead);
            streamToClient.flush();
          }
        } catch (IOException e) {
        }

        // The server closed its connection to us, so we close our
        // connection to our client.
        streamToClient.close();
      } catch (IOException e) {
        System.err.println(e);
      } finally {
        try {
          if (server != null)
            server.close();
          if (client != null)
            client.close();
        } catch (IOException e) {
        }
      }
    }
  }
}
